package com.school.edupoint.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@Slf4j
public class RedisConfiguration {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建 Redis 模板对象");

        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
//        设置连接工厂
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 设置 key 的序列化器···········································
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());

        // 创建 JSON 序列化器 - 指定具体类型
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
//        开启 JSON 中的类型信息（@class），用于反序列化
        mapper.activateDefaultTyping(
                mapper.getPolymorphicTypeValidator(),
                ObjectMapper.DefaultTyping.NON_FINAL
        );
//        创建 Java 对象的 JSON 序列化器·······························
        Jackson2JsonRedisSerializer<Object> jsonSerializer = new Jackson2JsonRedisSerializer<>(
                mapper, Object.class);
//      设置 value 的序列化器···································
        // Redis只能存储字节数据(byte[])
        // ，redisTemplate.opsForValue().set("key", activity) 时，activity 就会被这个 JSON 序列化器处理。
        redisTemplate.setValueSerializer(jsonSerializer);
//        设置 hash value 的序列化器
        redisTemplate.setHashValueSerializer(jsonSerializer);


        return redisTemplate;
    }
}